Skip to content

Support mixed-form sequence lengths in SDPA forward (cuDNN 9.26+)#430

Open
egilliam-nv wants to merge 1 commit into
NVIDIA:developfrom
egilliam-nv:feature/cu_seqlens_mixed
Open

Support mixed-form sequence lengths in SDPA forward (cuDNN 9.26+)#430
egilliam-nv wants to merge 1 commit into
NVIDIA:developfrom
egilliam-nv:feature/cu_seqlens_mixed

Conversation

@egilliam-nv

@egilliam-nv egilliam-nv commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Before submitting

  • I agree to license this contribution under the terms of LICENSE.txt.
  • I ran pre-commit run and committed any formatting changes.

Affected area

  • C++ frontend API or graph construction (SDPA support surface, diagonal band mask)
  • Python API or bindings (SDPA test harness)

Summary

Allow the Q and KV sides of SDPA forward to independently choose their sequence-length representation: per-batch (seq_len_*) or cumulative (cu_seq_len_*). Previously the two forms were mutually exclusive across the whole operation.

  • sdpa_support_surface: validation is now per-side (exactly one form per side; both sides provided together); the paged requirement accepts either form per side; mixed forms are gated on cuDNN 9.26+ in the UNIFIED surface. A has_input helper is hoisted for the presence checks.
  • diagonal_band_mask: the node's metadata seqlen check is relaxed to per-side exclusivity, matching the SDPA rules.
  • Tests: per-side form control in the SDPA test harness (cu_seq_len_sides) plus a deterministic mixed-form test (test_sdpa_mixed_seq_len_forms_L0) with non-uniform per-batch lengths, including bottom-right-causal cases that guard the backend's band-mask alignment derivation.

Why

Paged-attention integrations naturally hold a cumulative Q prefix sum (qo_indptr) alongside per-batch KV lengths. The old same-form-both-sides rule forced them to materialize a KV-side prefix sum purely to satisfy the pairing constraint. Permitting mixed forms removes that unnecessary conversion.

The 9.26 floor is deliberate: the initial public cuDNN 9.25 release predates the backend-side support, and a later "9.25" build carrying it cannot be distinguished from one without it (backend_version() reports the same 92500), so mixed forms are only advertised at 9.26+.

Related issues

Backend support merged separately (cuDNN backend MRs, internal). Related to #366 (expose cu_seq_len_q/kv on the sdpa_fp8 Python binding).

API and compatibility impact

No public API additions or removals. Purely relaxes an existing validation constraint on the cu_seq_len_* / seq_len_* SDPA inputs; all previously-valid graphs remain valid. New capability (mixed forms) is version-gated to cuDNN 9.26+ and rejected with a clear error below that.

Testing

On H100 (sm90) against a cuDNN 9.27 dev build with the backend support:

  • pytest test/python/test_mhas_v2.py -k mixed_seq_len_forms — 4/4 pass (both mixed directions x {top-left, bottom-right-causal}).
  • pytest test/python/test_sdpa_edge_cases.py — 10/10 pass (no harness regression).
  • pytest test/python/test_mhas_v2.py::test_sdpa_random_fwd_L0 (slice) — 203 passed, 9 skipped.
  • Standalone end-to-end check: non-paged mixed (both directions), and paged ragged-Q + page tables with cu_seq_len_q + seq_len_kv and bottom-right causal, all match the both-per-batch reference.

Below cuDNN 9.26 the mixed-form tests skip via the version gate.

Summary by CodeRabbit

  • New Features

    • Added support for mixed sequence-length formats, allowing query and key/value sides to use different representations.
    • Expanded attention validation for padding masks, paged attention, and sequence-length combinations.
  • Bug Fixes

    • Improved validation errors for incompatible sequence-length inputs.
  • Tests

    • Added coverage for mixed sequence-length configurations, including different mask alignments and attention boundaries.

Allow the Q and KV sides of SDPA forward to independently choose their
sequence length representation: per-batch (seq_len_*) or cumulative
(cu_seq_len_*). Previously the two forms were mutually exclusive across
the whole operation, forcing paged-attention integrations -- whose
natural state is a cumulative Q prefix sum alongside per-batch KV
lengths -- to materialize a KV-side prefix sum purely to satisfy the
pairing rule.

- sdpa_support_surface: validation is now per-side (exactly one form
  per side, sides provided together); the paged requirement accepts
  either form per side; mixed forms are gated on cuDNN 9.26+ in the
  UNIFIED surface (the initial public 9.25 release predates the
  backend-side support, and a 9.25 build that has it cannot be told
  apart from one that does not). Hoist a has_input helper for the
  presence checks.
- diagonal_band_mask: relax the node's metadata seqlen check to
  per-side exclusivity, matching the SDPA rules.
- tests: per-side form control in the SDPA test harness
  (cu_seq_len_sides) and a deterministic mixed-form test with
  non-uniform lengths, including bottom-right causal cases that guard
  the backend's band-mask alignment derivation.

Validated on H100 against a cuDNN 9.27 dev build: mixed forms in both
directions match the both-per-batch reference for non-paged, ragged,
and paged (ragged Q + page tables, cu_seq_len_q + seq_len_kv) graphs;
the deterministic tests skip below the version gate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 6f1c9dd1-fdb9-4cf5-a127-932a1e30a901

📥 Commits

Reviewing files that changed from the base of the PR and between 3a9ed3f and da67de4.

📒 Files selected for processing (5)
  • include/cudnn_frontend/node/diagonal_band_mask.h
  • include/cudnn_frontend/node/sdpa_support_surface.h
  • test/python/sdpa/fp16.py
  • test/python/sdpa/random_config.py
  • test/python/test_mhas_v2.py

📝 Walkthrough

Walkthrough

SDPA validation now supports independently selected explicit or cumulative sequence-length forms for Q and KV. Test configuration, tensor allocation, graph construction, version gating, and parameterized mixed-form coverage are updated accordingly.

Changes

Mixed sequence-length support

Layer / File(s) Summary
Sequence-length validation rules
include/cudnn_frontend/node/diagonal_band_mask.h, include/cudnn_frontend/node/sdpa_support_surface.h
Validation distinguishes Q/KV sequence-length representations, updates padding-mask and paged-attention checks, and enforces implementation-specific cumulative sequence-length constraints.
Per-side test configuration and graph wiring
test/python/sdpa/random_config.py, test/python/sdpa/fp16.py
ExecConfig selects cumulative forms independently for Q and KV, while tensor allocation and forward-graph construction provide the matching inputs.
Deterministic mixed-form coverage
test/python/test_mhas_v2.py
A parameterized test covers Q-only and KV-only cumulative sequence-length cases with diagonal alignment and right-bound variations.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ExecConfig
  participant allocate_tensors
  participant create_forward_graph
  participant SDPA_attributes
  ExecConfig->>allocate_tensors: select Q and KV sequence-length forms
  allocate_tensors->>create_forward_graph: provide explicit or cumulative tensors
  create_forward_graph->>SDPA_attributes: validate mixed-form inputs
  SDPA_attributes-->>create_forward_graph: accept or reject configuration
Loading

Suggested reviewers: anerudhan

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: mixed-form SDPA sequence lengths with a cuDNN version gate.
Description check ✅ Passed The description matches the template well and includes the required sections for scope, motivation, issues, compatibility, and testing.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@egilliam-nv egilliam-nv added cat-enhancements mod-frontend cuDNN frontend APIs, operation graph construction, plans, and user-facing wrappers. orig-nv-eng Reported or requested by NVIDIA engineering. labels Jul 23, 2026
@egilliam-nv egilliam-nv self-assigned this Jul 23, 2026
@egilliam-nv

Copy link
Copy Markdown
Collaborator Author

@cudnn-ci-bot run

@egilliam-nv
egilliam-nv requested a review from vedaanta July 23, 2026 17:18
@cudnn-ci-bot

Copy link
Copy Markdown

🚀 Running mirror pipeline

Branch: cudnn-gh/pr-430-da67de4
Pipeline: 59279176

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cat-enhancements mod-frontend cuDNN frontend APIs, operation graph construction, plans, and user-facing wrappers. orig-nv-eng Reported or requested by NVIDIA engineering.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants